package com.sy.olddriver.service.impl;

import com.sy.olddriver.constant.AppConstant;
import com.sy.olddriver.dao.ProductDao;
import com.sy.olddriver.dao.impl.ProductDaoImpl;
import com.sy.olddriver.entity.Product;
import com.sy.olddriver.entity.User;
import com.sy.olddriver.service.HistoryService;
import com.sy.olddriver.service.UserService;
import com.sy.olddriver.utils.CookieUtils;
import com.sy.olddriver.utils.RedisUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

public class HistoryServiceImpl implements HistoryService {
    private UserService userService = new UserServiceImpl();
    private ProductDao productDao = new ProductDaoImpl();

    @Override
    public void addHistory(String pid, HttpServletRequest req, HttpServletResponse res) {
        //浏览商品以后，添加商品的浏览历史记录
        User user = userService.getLoginUser(CookieUtils.getCookie(AppConstant.COOKIE_USER_TOKEN_NAME, req));
        //未登录状态下
        if (user == null) {
            String tempHistory = CookieUtils.getCookie(AppConstant.COOKIE_TEMP_HISTORY, req);
            //如果Cookie中没有用来保存浏览记录的name
            if (StringUtils.isBlank(tempHistory)) {
                //此时创建新的Cookie，其中的值即为现在浏览的记录
                CookieUtils.addCookie(AppConstant.COOKIE_TEMP_HISTORY, pid, res);
            }
            //如果已经存在Cookie，则将新的浏览记录添加到原来记录之前
            else {
                String[] pids = tempHistory.split("\\|");
                Deque<String> pidList = new LinkedList<>();
                Arrays.stream(pids).forEach(e -> pidList.add(e));
                pidList.remove(pid);
                pidList.addFirst(pid);
                CookieUtils.addCookie(AppConstant.COOKIE_TEMP_HISTORY, pidList.stream().collect(Collectors.joining("|")), res);
            }
        } else {
            //如果是登录状态下，则直接向redis存储数据
            String historyKey = AppConstant.REDIS_HISTORY_KEY_PREFIX + user.getId();
            //先删除redis已经存在的编号，避免重复
            RedisUtils.lrem(historyKey, 1L, pid);
            //存入新的记录
            RedisUtils.lpush(historyKey, pid);
        }
    }

    @Override
    public void mergeHistory(HttpServletRequest req, HttpServletResponse res, User user) {
        Integer userId = user.getId();
        String cookiPidsStr = CookieUtils.getCookie(AppConstant.COOKIE_TEMP_HISTORY, req);
        if (StringUtils.isNotBlank(cookiPidsStr)) {
            String[] cookiePids = cookiPidsStr.split("\\|");
            String key = AppConstant.REDIS_HISTORY_KEY_PREFIX + userId;
            Arrays.stream(cookiePids).forEach(id -> {
                //先删除重复记录
                RedisUtils.lrem(key, 1L, id);
                //再加入新的记录
                RedisUtils.rpush(key, id);
            });
            //删除cookie中的记录
            CookieUtils.deleteCookie(AppConstant.COOKIE_TEMP_HISTORY, req, res);
        }
    }

    @Override
    public List<Product> getAllHistories(HttpServletRequest req, HttpServletResponse res) {
        String token = CookieUtils.getCookie(AppConstant.COOKIE_USER_TOKEN_NAME, req);
        User user = userService.getLoginUser(token);
        List<String> pidList = new ArrayList<>();
        if (user == null) {
            String tempHistory = CookieUtils.getCookie(AppConstant.COOKIE_TEMP_HISTORY, req);
            if (StringUtils.isNotBlank(tempHistory)) {
                String[] pids = tempHistory.split("\\|");
                pidList = Arrays.asList(pids);
            }
        } else {
            pidList = RedisUtils.lrange(AppConstant.REDIS_HISTORY_KEY_PREFIX + user.getId(), 0L, -1L);
            System.out.println(pidList);
        }
        if (CollectionUtils.isEmpty(pidList)) {
            return new ArrayList<>();
        }
        return productDao.getProductsByPids(pidList);
    }
}
